"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _vue = require("vue");
var _xeUtils = _interopRequireDefault(require("xe-utils"));
var _ui = require("../../ui");
var _vn = require("../../ui/src/vn");
var _defaultSettingData = require("./default-setting-data");
var _form = _interopRequireDefault(require("../../form/src/form"));
var _formGroup = _interopRequireDefault(require("../../form/src/form-group"));
var _formItem = _interopRequireDefault(require("../../form/src/form-item"));
var _widgetInfo = require("./widget-info");
var _log = require("../../ui/src/log");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _default = exports.default = (0, _vue.defineComponent)({
  name: 'VxeFormView',
  props: {
    modelValue: Object,
    config: Object,
    readonly: Boolean,
    disabled: Boolean,
    viewRender: Object,
    formOptions: Object,
    createFormConfig: Function,
    size: {
      type: String,
      default: () => (0, _ui.getConfig)().formView.size || (0, _ui.getConfig)().size
    }
  },
  emits: ['update:modelValue', 'submit', 'reset'],
  setup(props, context) {
    const {
      emit,
      slots
    } = context;
    const xID = _xeUtils.default.uniqueId();
    const refElem = (0, _vue.ref)();
    const formRef = (0, _vue.ref)();
    const {
      computeSize
    } = (0, _ui.useSize)(props);
    const $xeFormDesignLayoutStyle = (0, _vue.inject)('$xeFormDesignLayoutStyle', null);
    const reactData = (0, _vue.reactive)({
      formConfig: {},
      formRules: {},
      widgetObjList: []
    });
    const refMaps = {
      refElem
    };
    const computeMaps = {
      computeSize
    };
    const $xeFormView = {
      xID,
      props,
      context,
      reactData,
      getRefMaps: () => refMaps,
      getComputeMaps: () => computeMaps
    };
    const clearConfig = () => {
      return loadConfig({
        formConfig: {},
        widgetData: []
      });
    };
    const loadConfig = config => {
      if (config) {
        const {
          formConfig,
          widgetData
        } = config;
        loadFormConfig(formConfig || {});
        loadWidgetData(widgetData || []);
      }
      return (0, _vue.nextTick)();
    };
    const parseConfig = config => {
      const {
        formConfig,
        widgetData
      } = config || {};
      const widgetObjList = parseWidgetData(widgetData || []);
      return Object.assign(Object.assign({}, parseForm(widgetObjList)), {
        formConfig: parseFormConfig(formConfig || {}),
        widgetData: widgetObjList
      });
    };
    const parseFormConfig = formConfig => {
      const {
        viewRender,
        createFormConfig,
        formOptions
      } = props;
      const params = {
        viewRender,
        formConfig
      };
      if (createFormConfig) {
        return createFormConfig(params);
      }
      const {
        name
      } = viewRender || {};
      const compConf = _ui.renderer.get(name) || {};
      const createPCFormConfig = compConf ? compConf.createFormViewFormConfig : null;
      return Object.assign({}, createPCFormConfig ? createPCFormConfig(params) : (0, _defaultSettingData.createDefaultFormViewPCFormConfig)(params), formOptions);
    };
    const loadFormConfig = formConfig => {
      reactData.formConfig = parseFormConfig(formConfig);
      return (0, _vue.nextTick)();
    };
    const parseForm = widgetObjList => {
      const formData = {};
      const formRules = {};
      _xeUtils.default.eachTree(widgetObjList, widget => {
        const {
          name,
          field,
          required
        } = widget;
        const compConf = _ui.renderer.get(name) || {};
        const createWidgetFieldValue = compConf.createFormDesignWidgetFieldValue;
        const createWidgetFieldRules = compConf.createFormDesignWidgetFieldRules;
        formData[field] = createWidgetFieldValue ? createWidgetFieldValue({
          widget,
          $formView: $xeFormView
        }) : getWidgetDefaultValue(widget);
        if (createWidgetFieldRules) {
          const rules = createWidgetFieldRules({
            widget,
            $formView: $xeFormView
          });
          if (rules && rules.length) {
            formRules[field] = rules;
          }
        } else if (required) {
          formRules[field] = getWidgetDefaultRule();
        }
      }, {
        children: 'children'
      });
      return {
        formData,
        formRules
      };
    };
    const parseWidgetData = widgetData => {
      return (widgetData || []).map(item => (0, _widgetInfo.configToWidget)(item));
    };
    const loadWidgetData = widgetData => {
      const widgetObjList = parseWidgetData(widgetData);
      reactData.widgetObjList = widgetObjList;
      const {
        formData,
        formRules
      } = parseForm(widgetObjList);
      reactData.formRules = formRules;
      emit('update:modelValue', Object.assign(formData, props.modelValue));
      return (0, _vue.nextTick)();
    };
    const getWidgetDefaultValue = widget => {
      switch (widget.name) {
        case 'subtable':
          return [];
      }
      return null;
    };
    const getWidgetDefaultRule = () => {
      return [{
        required: true,
        content: '该填写该字段！'
      }];
    };
    const updateWidgetStatus = (widget, value) => {
      const {
        field
      } = widget;
      const $form = formRef.value;
      if ($form) {
        $form.updateStatus({
          field
        }, value);
      }
      return (0, _vue.nextTick)();
    };
    const setItemValue = (widget, value) => {
      const {
        modelValue
      } = props;
      const {
        field
      } = widget;
      const $form = formRef.value;
      if (modelValue) {
        modelValue[field] = value;
      }
      if ($form) {
        $form.updateStatus({
          field
        }, value);
      }
      return (0, _vue.nextTick)();
    };
    const getItemValue = widget => {
      const {
        modelValue
      } = props;
      if (modelValue) {
        return modelValue[widget.field];
      }
      return null;
    };
    const dispatchEvent = (type, params, evnt) => {
      emit(type, (0, _ui.createEvent)(evnt, {
        $formView: $xeFormView
      }, params));
    };
    const toWidgetFields = widget => {
      if (widget) {
        if (_xeUtils.default.isArray(widget)) {
          return widget.map(item => item.name);
        } else {
          return [widget.name];
        }
      }
      return null;
    };
    const formViewMethods = {
      dispatchEvent,
      clearConfig,
      loadConfig,
      parseConfig,
      loadFormConfig,
      loadWidgetData,
      updateWidgetStatus,
      setItemValue,
      getItemValue,
      validate() {
        const $form = formRef.value;
        if ($form) {
          return $form.validate();
        }
        return (0, _vue.nextTick)();
      },
      validateWidget(widget) {
        const $form = formRef.value;
        if ($form) {
          return $form.validateField(toWidgetFields(widget));
        }
        return (0, _vue.nextTick)();
      },
      clearValidate(widget) {
        const $form = formRef.value;
        if ($form) {
          return $form.clearValidate(toWidgetFields(widget));
        }
        return (0, _vue.nextTick)();
      },
      reset() {
        const {
          widgetObjList
        } = reactData;
        const {
          formData
        } = parseForm(widgetObjList);
        emit('update:modelValue', Object.assign({}, formData));
        return (0, _vue.nextTick)();
      },
      /**
       * 已废弃
       * @deprecated
       */
      updateItemStatus(widget, value) {
        if (process.env.NODE_ENV === 'development') {
          (0, _log.warnLog)('vxe.error.delFunc', ['updateItemStatus', 'updateWidgetStatus']);
        }
        return updateWidgetStatus(widget, value);
      }
    };
    const handleSubmit = params => {
      dispatchEvent('submit', params, params.$event);
    };
    const handleReset = params => {
      dispatchEvent('reset', params, params.$event);
    };
    const formViewPrivateMethods = {};
    Object.assign($xeFormView, formViewMethods, formViewPrivateMethods);
    const renderVN = () => {
      const {
        readonly,
        disabled,
        modelValue
      } = props;
      const {
        formConfig,
        formRules,
        widgetObjList
      } = reactData;
      const vSize = computeSize.value;
      const topSlot = slots.top;
      const bottomSlot = slots.bottom;
      const headerSlot = slots.header;
      const footerSlot = slots.footer;
      return (0, _vue.h)('div', {
        ref: refElem,
        class: ['vxe-form-view', {
          [`size--${vSize}`]: vSize
        }]
      }, [topSlot ? (0, _vue.h)('div', {
        class: 'vxe-form-view--top'
      }, (0, _vn.getSlotVNs)(topSlot({
        $formView: $xeFormView
      }))) : (0, _vue.createCommentVNode)(), (0, _vue.h)(_form.default, Object.assign(Object.assign({
        ref: formRef
      }, formConfig), {
        data: modelValue,
        customLayout: true,
        readonly,
        disabled,
        span: 24,
        rules: formRules,
        onSubmit: handleSubmit,
        onReset: handleReset
      }), {
        default() {
          const {
            readonly,
            disabled
          } = props;
          return [headerSlot ? (0, _vue.h)(_formItem.default, {}, {
            default() {
              return headerSlot({});
            }
          }) : (0, _vue.createCommentVNode)(), ...widgetObjList.map(widget => {
            const {
              name
            } = widget;
            const compConf = _ui.renderer.get(name) || {};
            const renderWidgetDesignView = compConf.renderFormDesignWidgetView;
            const renderWidgetDesignPreview = compConf.renderFormDesignWidgetPreview;
            const renderWidgetDesignMobilePreview = compConf.renderFormDesignWidgetMobilePreview;
            const isEditMode = !!$xeFormDesignLayoutStyle;
            const renderOpts = widget;
            const params = {
              widget,
              readonly: !!readonly,
              disabled: !!disabled,
              isEditMode,
              isViewMode: !isEditMode,
              $formDesign: null,
              $formView: $xeFormView
            };
            return (0, _vue.h)(_formGroup.default, {
              key: widget.id
            }, {
              default() {
                // 如果处于表单设计器-样式设置-预览模式下
                if ($xeFormDesignLayoutStyle) {
                  if ($xeFormDesignLayoutStyle.reactData.activeTab === 2) {
                    if (renderWidgetDesignMobilePreview) {
                      return (0, _vn.getSlotVNs)(renderWidgetDesignMobilePreview(renderOpts, params));
                    }
                  } else {
                    if (renderWidgetDesignPreview) {
                      return (0, _vn.getSlotVNs)(renderWidgetDesignPreview(renderOpts, params));
                    }
                  }
                }
                return renderWidgetDesignView ? (0, _vn.getSlotVNs)(renderWidgetDesignView(renderOpts, params)) : [];
              }
            });
          }), footerSlot ? (0, _vue.h)(_formGroup.default, {
            span: 24
          }, {
            default() {
              return footerSlot({});
            }
          }) : (0, _vue.createCommentVNode)()];
        }
      }), bottomSlot ? (0, _vue.h)('div', {
        class: 'vxe-form-view--bottom'
      }, (0, _vn.getSlotVNs)(bottomSlot({
        $formView: $xeFormView
      }))) : (0, _vue.createCommentVNode)()]);
    };
    $xeFormView.renderVN = renderVN;
    (0, _vue.watch)(() => props.config, value => {
      loadConfig(value || {});
    });
    if (props.config) {
      loadConfig(props.config);
    }
    (0, _vue.provide)('$xeFormView', $xeFormView);
    return $xeFormView;
  },
  render() {
    return this.renderVN();
  }
});